import { http } from "@/utils/http";
import type { ApiResponse } from "../../user";
import { ensureArray, normalisePagination, toNumber } from "@/api/_helpers";

const ITEM_BASE = "/system/product/item";
const BULK_UPLOAD_ENDPOINT = `${ITEM_BASE}/bulk-upload`;
const BRAND_ENDPOINT = "/system/product/brand";
const CATEGORY_ENDPOINT = "/system/product/category";

export const PRODUCT_STATUS_MAP: Record<number, string> = {
  0: "草稿",
  1: "上架",
  2: "下架",
  3: "禁用"
};

export const PRODUCT_AUDIT_STATUS_MAP: Record<number, string> = {
  0: "待审核",
  1: "已通过",
  2: "已驳回"
};

export interface ProductListParams {
  page?: number;
  page_size?: number;
  keyword?: string;
  status?: number | string;
  audit_status?: number | string;
  category_id?: number | string;
  brand_id?: number | string;
  seller_org_id?: number | string;
}

export interface ProductListItem {
  id: number;
  title: string;
  subtitle: string;
  model: string;
  sku_code: string;
  region_id: number | null;
  seller_org_id: number;
  seller_user_id: number | null;
  category_id: number;
  category?: { id: number; name: string } | null;
  brand_id: number | null;
  brand?: { id: number; name: string } | null;
  default_price: number;
  default_stock: number;
  unit: string;
  status: number;
  audit_status: number;
  publish_time: string | null;
  create_time?: string;
  update_time?: string;
  [key: string]: any;
}

export interface ProductPagination {
  total: number;
  pageSize: number;
  currentPage: number;
}

export interface ProductListResult {
  list: ProductListItem[];
  pagination: ProductPagination;
}

export interface ProductDetail extends ProductListItem {
  min_order_qty: number | null;
  step_qty: number | null;
  weight_value: number | null;
  weight_unit: string;
  size_length: number | null;
  size_width: number | null;
  size_height: number | null;
  origin_country: string;
  manufactured_at: string | null;
  summary: string;
  description: string;
  attachments: Array<Record<string, any>>;
  attributes: Array<Record<string, any>>;
  gallery: string[];
  videos: string[];
  remark: string;
}

export interface ProductSubmitPayload {
  seller_org_id?: number | null;
  seller_user_id?: number | null;
  region_id?: number | null;
  category_id: number;
  brand_id?: number | null;
  title: string;
  subtitle?: string;
  model?: string;
  sku_code?: string;
  default_price: number;
  default_stock: number;
  unit?: string;
  min_order_qty?: number | null;
  step_qty?: number | null;
  weight_value?: number | null;
  weight_unit?: string;
  size_length?: number | null;
  size_width?: number | null;
  size_height?: number | null;
  origin_country?: string;
  manufactured_at?: string | null;
  summary?: string;
  description?: string;
  attachments?: Array<Record<string, any>>;
  attributes?: Array<Record<string, any>>;
  gallery?: string[];
  videos?: string[];
  status?: number;
  audit_status?: number;
  publish_time?: string | null;
  remark?: string;
}

export interface BulkUploadJobResult {
  job_id: number;
  status: string;
  total_rows: number;
  chunk_size: number;
  created_at: string;
  duplicate?: boolean;
}

const mapListItem = (item: Record<string, any>): ProductListItem => {
  const brand = item.brand ?? null;
  const category = item.category ?? null;

  return {
    id: toNumber(item.id, 0),
    title: item.title ?? "",
    subtitle: item.subtitle ?? "",
    model: item.model ?? "",
    sku_code: item.sku_code ?? "",
    region_id: item.region_id !== null ? toNumber(item.region_id, null) : null,
    seller_org_id: toNumber(item.seller_org_id, 0),
    seller_user_id:
      item.seller_user_id !== null ? toNumber(item.seller_user_id, null) : null,
    category_id: toNumber(item.category_id, 0),
    category: category
      ? { id: toNumber(category.id, 0), name: category.name ?? "" }
      : null,
    brand_id: item.brand_id !== null ? toNumber(item.brand_id, null) : null,
    brand: brand ? { id: toNumber(brand.id, 0), name: brand.name ?? "" } : null,
    default_price: toNumber(item.default_price, 0),
    default_stock: toNumber(item.default_stock, 0),
    unit: item.unit ?? "",
    status: toNumber(item.status, 0),
    audit_status: toNumber(item.audit_status, 0),
    publish_time: item.publish_time ?? null,
    create_time: item.create_time ?? "",
    update_time: item.update_time ?? "",
    origin_country: item.origin_country ?? ""
  };
};

const mapDetail = (item: Record<string, any>): ProductDetail => {
  const base = mapListItem(item);

  const gallery = ensureArray<string>(item.gallery ?? []).filter(
    url => typeof url === "string" && url !== ""
  );
  const videos = ensureArray<string>(item.videos ?? []).filter(
    url => typeof url === "string" && url !== ""
  );
  const attachments = ensureArray<Record<string, any>>(item.attachments ?? []);
  const attributes = ensureArray<Record<string, any>>(item.attributes ?? []);

  return {
    ...base,
    region_id: item.region_id !== null ? toNumber(item.region_id, null) : null,
    min_order_qty:
      item.min_order_qty !== null ? toNumber(item.min_order_qty, null) : null,
    step_qty: item.step_qty !== null ? toNumber(item.step_qty, null) : null,
    weight_value: item.weight_value !== null ? Number(item.weight_value) : null,
    weight_unit: item.weight_unit ?? "",
    size_length: item.size_length !== null ? Number(item.size_length) : null,
    size_width: item.size_width !== null ? Number(item.size_width) : null,
    size_height: item.size_height !== null ? Number(item.size_height) : null,
    origin_country: item.origin_country ?? "",
    manufactured_at: item.manufactured_at ?? null,
    summary: item.summary ?? "",
    description: item.description ?? "",
    attachments,
    attributes,
    gallery,
    videos,
    remark: item.remark ?? ""
  };
};

const mapSubmitPayload = (
  payload: ProductSubmitPayload
): Record<string, any> => {
  const data: Record<string, any> = {
    seller_org_id:
      payload.seller_org_id !== undefined ? payload.seller_org_id : null,
    seller_user_id: payload.seller_user_id ?? null,
    category_id: payload.category_id,
    brand_id: payload.brand_id ?? null,
    title: payload.title,
    subtitle: payload.subtitle ?? "",
    model: payload.model ?? "",
    sku_code: payload.sku_code ?? "",
    default_price: Number(payload.default_price ?? 0),
    default_stock: Number(payload.default_stock ?? 0),
    unit: payload.unit ?? "",
    min_order_qty:
      payload.min_order_qty !== undefined ? payload.min_order_qty : null,
    step_qty: payload.step_qty !== undefined ? payload.step_qty : null,
    weight_value:
      payload.weight_value !== undefined ? payload.weight_value : null,
    weight_unit: payload.weight_unit ?? "",
    size_length: payload.size_length !== undefined ? payload.size_length : null,
    size_width: payload.size_width !== undefined ? payload.size_width : null,
    size_height: payload.size_height !== undefined ? payload.size_height : null,
    origin_country: payload.origin_country ?? "",
    manufactured_at: payload.manufactured_at ?? null,
    summary: payload.summary ?? "",
    description: payload.description ?? "",
    attachments: ensureArray(payload.attachments ?? []),
    attributes: ensureArray(payload.attributes ?? []),
    gallery: ensureArray(payload.gallery ?? []),
    videos: ensureArray(payload.videos ?? []),
    remark: payload.remark ?? "",
    status:
      payload.status !== undefined && payload.status !== null
        ? Number(payload.status)
        : 0,
    audit_status:
      payload.audit_status !== undefined && payload.audit_status !== null
        ? Number(payload.audit_status)
        : 0,
    publish_time: payload.publish_time ?? null
  };

  if (data.gallery.length && !data.cover_image) {
    data.cover_image = data.gallery[0];
  } else if (payload.gallery) {
    data.cover_image = data.gallery?.length ? data.gallery[0] : null;
  }

  const sellerOrgId = Number(data.seller_org_id);
  if (!Number.isFinite(sellerOrgId) || sellerOrgId <= 0) {
    delete data.seller_org_id;
  } else {
    data.seller_org_id = sellerOrgId;
  }

  return data;
};

export const fetchList = async (
  params: ProductListParams = {}
): Promise<ProductListResult> => {
  const page = toNumber(params.page, 1) || 1;
  const pageSize = toNumber(params.page_size, 10) || 10;

  const res = await http.request<ApiResponse<any>>("get", ITEM_BASE, {
    params: {
      ...params,
      page,
      page_size: pageSize
    }
  });

  const payload = (res?.data ?? {}) as Record<string, any>;
  const list = ensureArray(payload.list ?? payload.data ?? []).map(mapListItem);
  const pagination = normalisePagination(
    payload.pagination ?? payload,
    page,
    pageSize,
    list.length
  );

  return {
    list,
    pagination
  };
};

export const fetchDetail = async (
  id: number | string
): Promise<ProductDetail> => {
  const res = await http.request<ApiResponse<Record<string, any>>>(
    "get",
    `${ITEM_BASE}/${id}`
  );
  return mapDetail(res.data ?? {});
};

export const createProduct = async (payload: ProductSubmitPayload) => {
  const data = mapSubmitPayload(payload);
  return http.request<ApiResponse<any>>("post", ITEM_BASE, { data });
};

export const updateProduct = async (
  id: number | string,
  payload: ProductSubmitPayload
) => {
  const data = mapSubmitPayload(payload);
  return http.request<ApiResponse<any>>("put", `${ITEM_BASE}/${id}`, {
    data
  });
};

export const removeProduct = async (id: number | string) => {
  return http.request<ApiResponse<boolean>>("delete", `${ITEM_BASE}/${id}`);
};

export const batchUpdateStatus = async (
  ids: Array<number | string>,
  status: number
) => {
  if (!Array.isArray(ids) || ids.length === 0) {
    return {
      code: 200,
      success: true,
      msg: "无可更新商品",
      data: true
    };
  }

  await Promise.all(
    ids.map(id =>
      http.request<ApiResponse<any>>("put", `${ITEM_BASE}/${id}`, {
        data: { status }
      })
    )
  );

  return {
    code: 200,
    success: true,
    msg: "状态已更新",
    data: true
  };
};

export const fetchBrandOptions = async () => {
  const res = await http.request<ApiResponse<any>>("get", BRAND_ENDPOINT, {
    params: {
      page: 1,
      page_size: 200
    }
  });

  const payload = (res?.data ?? {}) as Record<string, any>;
  const list = ensureArray(payload.list ?? payload.data ?? []);
  return list.map((item: any) => ({
    id: toNumber(item.id, 0),
    name: item.name ?? "",
    slug: item.slug ?? ""
  }));
};

export interface CategoryTreeNode {
  id: number;
  name: string;
  children?: CategoryTreeNode[];
  [key: string]: any;
}

export const fetchCategoryTree = async () => {
  const res = await http.request<ApiResponse<any>>("get", CATEGORY_ENDPOINT, {
    params: {
      as_tree: true
    }
  });

  const payload = ensureArray<CategoryTreeNode>(res?.data ?? []);
  return payload;
};

export const bulkUpload = async (
  formData: FormData
): Promise<BulkUploadJobResult> => {
  const res = await http.request<ApiResponse<Record<string, any>>>(
    "post",
    BULK_UPLOAD_ENDPOINT,
    {
      data: formData,
      headers: {
        "Content-Type": "multipart/form-data"
      },
      timeout: 60_000
    }
  );

  const data = res?.data ?? {};
  return {
    job_id: toNumber(data.job_id, 0),
    status: data.status ?? "pending",
    total_rows: toNumber(data.total_rows, 0),
    chunk_size: toNumber(data.chunk_size, 20),
    created_at: data.created_at ?? "",
    duplicate: Boolean(data.duplicate)
  };
};

export interface ImportJobListParams {
  page?: number;
  page_size?: number;
  status?: string;
}

export interface ImportJobItem {
  id: number;
  seller_org_id: number;
  seller_user_id: number | null;
  status: string;
  total_rows: number;
  success_count: number;
  fail_count: number;
  chunk_size: number;
  current_index: number;
  created_at: string;
  started_at?: string | null;
  finished_at?: string | null;
}

export interface ImportJobListResult {
  list: ImportJobItem[];
  pagination: ProductPagination;
}

export interface ImportJobDetail extends ImportJobItem {
  error_log: string[];
}

export const fetchImportJobs = async (
  params: ImportJobListParams = {}
): Promise<ImportJobListResult> => {
  const page = toNumber(params.page, 1) || 1;
  const pageSize = toNumber(params.page_size, 10) || 10;

  const res = await http.request<ApiResponse<any>>(
    "get",
    "/system/product/import-job",
    {
      params: {
        ...params,
        page,
        page_size: pageSize
      }
    }
  );

  const payload = (res?.data ?? {}) as Record<string, any>;
  const list = ensureArray<Record<string, any>>(payload.list ?? payload.data ?? []);
  const mapped = list.map((item: any) => ({
    id: toNumber(item.id, 0),
    seller_org_id: toNumber(item.seller_org_id, 0),
    seller_user_id:
      item.seller_user_id !== null ? toNumber(item.seller_user_id, null) : null,
    status: item.status ?? "",
    total_rows: toNumber(item.total_rows, 0),
    success_count: toNumber(item.success_count, 0),
    fail_count: toNumber(item.fail_count, 0),
    chunk_size: toNumber(item.chunk_size, 0),
    current_index: toNumber(item.current_index, 0),
    created_at: item.created_at ?? "",
    started_at: item.started_at ?? null,
    finished_at: item.finished_at ?? null
  }));

  const pagination = normalisePagination(
    payload.pagination ?? payload,
    page,
    pageSize,
    mapped.length
  );

  return {
    list: mapped,
    pagination
  };
};

export const fetchImportJobDetail = async (
  id: number | string
): Promise<ImportJobDetail> => {
  const res = await http.request<ApiResponse<Record<string, any>>>(
    "get",
    `/system/product/import-job/${id}`
  );
  const data = res?.data ?? {};
  return {
    id: toNumber(data.id, 0),
    seller_org_id: toNumber(data.seller_org_id, 0),
    seller_user_id:
      data.seller_user_id !== null ? toNumber(data.seller_user_id, null) : null,
    status: data.status ?? "",
    total_rows: toNumber(data.total_rows, 0),
    success_count: toNumber(data.success_count, 0),
    fail_count: toNumber(data.fail_count, 0),
    chunk_size: toNumber(data.chunk_size, 0),
    current_index: toNumber(data.current_index, 0),
    created_at: data.created_at ?? "",
    started_at: data.started_at ?? null,
    finished_at: data.finished_at ?? null,
    error_log: ensureArray<string>(data.error_log ?? [])
  };
};

export default {
  fetchList,
  fetchDetail,
  create: createProduct,
  update: updateProduct,
  remove: removeProduct,
  batchUpdateStatus,
  fetchBrandOptions,
  fetchCategoryTree,
  bulkUpload,
  fetchImportJobs,
  fetchImportJobDetail
};
